flock関数は、ファイルに対してロックの適用・解除を行います。ロックには、次の2種類があります。
- 共有ロック
- 他のプロセスからファイルを参照することはできますが、変更はできません。
- 排他ロック
- 他のプロセスからファイルの参照も変更もできません。
この関数は、C言語のライブラリ関数(標準関数)ではありませんので、コンパイラにより、使えない場合があります。
#include <sys/file.h>
int flock(int fd, int operation);
fdはopen関数又は、creat関数でファイルをオープンした時に取得した、ファイル・ディスクリプタを指定します。
operationはロックの種類を指定します。
戻り値として、処理が成功した場合は0が、エラーの場合は-1を返します。
第2引数のoperationには、次の値を指定できます。
値 | 意味 |
---|---|
LOCK_SH | 共有ロックを適用します。 |
LOCK_EX | 排他ロックを適用します。 |
LOCK_UN | ロックを解除します。 |
ロックを適用した複数のプロセスがファイルにアクセスすると、1つのプロセスのみがアクセスできて、その他のプロセスは停止(block)します。非停止(non-blocking)タイプの要求を行うには、上記の操作(operation)にLOCK_NBを論理和(OR)の形で指定します。また、1つのファイルに対して、共有ロックと排他ロックを同時に設定することはできません。
ロックの解除は第2引数のoperationにLOCK_UNを指定して実行するか、ファイルをクローズした場合に行われます。
プログラム 例
#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/file.h> int main(int argc, char **argv) { char pathname[] = './temp_lock.txt'; int fd; char out_buff[100]; int outcnt; int return_code = 0; /* 書き込み専用、追加モードでオープン */ if ((fd = open(pathname, O_WRONLY | O_APPEND)) != -1) { /* 排他ロックをかける */ if (flock(fd, LOCK_EX) == 0) { /* メッセージ出力 */ for (outcnt = 1; outcnt <= 3; ++outcnt) { sprintf(out_buff, '%s : %d回目\n', *(argv + 1), outcnt); write(fd, out_buff, strlen(out_buff)); sleep(2); } /* ロック解除 */ flock(fd, LOCK_UN); } else { perror(''); return_code = 2; } close(fd); } else { perror(''); return_code = 1; } return return_code; }
例の実行結果
flock.exe実行コマンドで、&記号を付けて並列実行を行っています。
$ cat temp_lock.txt This is temp_lock.txt. $ $ ./flock.exe Proc01 & [1] 2796 $ ./flock.exe Proc02 & [2] 2797 $ ./flock.exe Proc03 & [3] 2798 [1] Done ./flock.exe Proc01 $ ./flock.exe Proc04 & [4] 2799 [2] Done ./flock.exe Proc02 $ [3]- Done ./flock.exe Proc03 [4]+ Done ./flock.exe Proc04 $ cat temp_lock.txt This is temp_lock.txt. Proc01 : 1回目 Proc01 : 2回目 Proc01 : 3回目 Proc02 : 1回目 Proc02 : 2回目 Proc02 : 3回目 Proc03 : 1回目 Proc03 : 2回目 Proc03 : 3回目 Proc04 : 1回目 Proc04 : 2回目 Proc04 : 3回目 $